package JavaUtils.CSUtils.Log;


import JavaUtils.interfaceType.ILog;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;


public class CLog {
    public static String _tag = "tagNull";
    public static ILog o_logObj;


    public static void i(String tag, Object log) {
        if (log == null) {
            return;
        }
        _log(ELogType.e3_Log, tag, time(), log.toString(), S_GetInfo(2));
    }

    public static void i(String tag, String logStr) {
        if (logStr == null || "".equals(logStr)) {
            return;
        }
        _log(ELogType.e3_Log, tag, time(), logStr, S_GetInfo(2));
    }

    public static void f(String tag, String format, Object... args) {
        String logStr;
        if (args.length == 0) {
            logStr = format;
        } else {
            logStr = String.format(format, args);
        }
        _log(ELogType.e3_Log, tag, time(), logStr, S_GetInfo(2));
    }

    public static void w(String tag, String logStr) {
        if (logStr == null || "".equals(logStr)) {
            return;
        }
        _log(ELogType.e2_Warning, tag, time(), logStr, S_GetInfo(2));
    }

    public static void wf(String tag, String format, Object... args) {
        String logStr;
        if (args.length == 0) {
            logStr = format;
        } else {
            logStr = String.format(format, args);
        }
        _log(ELogType.e2_Warning, tag, time(), logStr, S_GetInfo(2));
    }

    public static void e(String tag, String logStr) {
        if (logStr == null) {
            return;
        }
        _log(ELogType.e0_Error, tag, time(), logStr, S_GetInfo(2));
    }

    public static void ef(String tag, String format, Object... args) {
        if (o_logObj != null) {
            String logStr;
            if (args.length == 0) {
                logStr = format;
            } else {
                logStr = String.format(format, args);
            }
            _log(ELogType.e0_Error, tag, time(), logStr, S_GetInfo(2));
        } else {
            System_Log(ELogType.e0_Error, String.format(format, args));
        }
    }


    public static void ex(String tag, String logStr) {
        if (logStr == null || "".equals(logStr)) {
            return;
        }
        _log(ELogType.e4_Exception, tag, time(), logStr, S_GetInfo(2));
    }

    public static void exf(String tag, String format, Object... args) {
        String logStr;
        if (args.length == 0) {
            logStr = format;
        } else {
            logStr = String.format(format, args);
        }
        _log(ELogType.e4_Exception, tag, time(), logStr, S_GetInfo(2));
    }

    public static void ex(String tag, String logStr, String stackTrace, boolean isAddStackTrace) {
        _log(ELogType.e4_Exception, tag, time(), logStr, stackTrace);
    }

    public static void ex(String tag, String logStr, Exception ex, boolean isAddStackTrace) {
        _log(ELogType.e4_Exception, tag, time(), logStr, S_GetInfo(ex));
    }

    public static void ex(String tag, String logStr, Exception e) {
        logStr = logStr + "__" + e.getMessage();
        _log(ELogType.e4_Exception, tag, time(), logStr, S_GetInfo(e, 0));
    }


    public static void _log(byte type, String tag, String time, String log, String stackTrace) {
        if (o_logObj != null) {
            o_logObj.AddLog(type, tag, time, log, stackTrace);
        } else {
            System_Log(type, log + "\n.." + stackTrace);
        }
    }

    static void System_Log(int type, String log) {
        switch (type) {
            case ELogType.e0_Error:
                System.out.println("\033[01;31m" + log + "\033[0m");
                break;
            case ELogType.e1_Assert:
                System.out.println("\033[32m" + log + "\033[0m");
                break;
            case ELogType.e2_Warning:
                System.out.println("\033[01;33m" + log + "\033[0m");
                break;
            case ELogType.e3_Log:
                System.out.println("\033[32m" + log + "\033[0m");
                break;
            case ELogType.e4_Exception:
                System.out.println("\033[32m" + log + "\033[0m");
                break;
        }

    }

    public static String S_GetInfo(Exception ex) {
        return S_GetInfo(ex, "", 0, "");
    }

    public static String S_GetInfo(Exception ex, String logStr) {
        return S_GetInfo(ex, logStr, 0, "");
    }

    public static String S_GetInfo(Exception ex, String logStr, int shieldLine) {
        return S_GetInfo(ex, logStr, shieldLine, "");
    }

    public static String S_GetInfo(Exception ex, String logStr, int shieldLine, String end) {
        StackTraceElement[] st = new Exception().getStackTrace();
        String logStr1 = String.format("%s...%s", logStr, ex.getMessage());
        return S_GetInfo(logStr1, st, shieldLine, end);
    }

    public static String S_GetInfo(String logStr, StackTraceElement[] st, int ShieldLine) {
        return S_GetInfo(logStr, st, ShieldLine, "");
    }

    public static String S_GetInfo(String logStr, StackTraceElement[] stack, int ShieldLine, String end) {
        if (stack == null) {
            stack = new Exception().getStackTrace();
        }
        StringBuilder ssb = new StringBuilder(logStr + "\n");
        for (int i = ShieldLine; i < stack.length; i++) {
            String fileName = stack[i].getMethodName();
            if (Objects.equals(fileName, "")) {
                continue;
            }
            StackTraceElement ss = stack[i];
            ssb.append(System.getProperty("user.dir"));
            ssb.append("___ ");
            ssb.append(ss.getClassName());
            ssb.append("/__ ");
            ssb.append(ss.getMethodName());
            ssb.append("(.)__ ");
            ssb.append(ss.getLineNumber());
            ssb.append("\n");
        }
        return ssb.toString();
    }


    public static String S_GetInfo(int startIndex) {
        return S_GetInfo(new Exception(), startIndex);
    }

    public static String S_GetInfo(Exception ex, int ShieldLine) {
        bb.setLength(0);
        StackTraceElement[] stack = ex.getStackTrace();
        for (int i = ShieldLine; i < stack.length; i++) {
            if (stack[i] == null) { continue; }
            bb.append(stack[i].getClassName()).append("__").append(stack[i].getMethodName());
            bb.append("___.(").append(stack[i].getFileName()).append(":").append(stack[i].getLineNumber()).append(")\n");
        }
        return bb.toString();
    }

    static StringBuilder bb = new StringBuilder();

    static Date date;

    static String time() {
        date = new Date();
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
    }
}
